from webbrowser import open_new_tab

from celery.utils.functional import pass1
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from apps.users.models import User
from django.contrib.auth import login,logout,authenticate
from utils.views import LoginRequiredJSONMixin
import json,re

# Create your views here.
##################判断用户名是否重复############################
class UsernameCountView(View):
    def get(self,request,username):
        """
        1.接受前端传来的参数
        2.后端业务逻辑：
        2.1 根据传来的username来数据库中查询
        2.2 使用count变量进行统计
        2.3 返回JSON数据 包括count errmsg
        """
        count = User.objects.filter(username=username).count()
        return JsonResponse({'code':0,'errmsg':'ok','count':count})

class MobileCountView(View):
    def get(self,request,mobile):
        """逻辑同上面差距不大"""
        count = User.objects.filter(mobile=mobile).count()
        return JsonResponse({'code':0,'errmsg':'ok','count':count})

class RegisterView(View):
    """
    用户注册的逻辑
    前端：用户点击注册按钮 发送一个axios 其中包含用户填写的个人信息
    后端：
        1.接受数据
            1.1 json数据 request.body
            1.2 字节流-》字符 。decode()
            1.3 字符串-》字典   json.loads
        2.业务逻辑
            2.1 数据判断，接受的数据是否齐全
            2.2 数据类型判断 数据的类型与预期是否相同
            2.3 将用户数据保存到mysql数据库
            2.4 是否需要状态保持 session-》redis
        3.返回数据
    """
    def post(self,request):

        json_dict = json.loads(request.body.decode())

        # 提取参数
        username = json_dict.get('username')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        mobile = json_dict.get('mobile')
        allow = json_dict.get('allow')
        sms_code = json_dict.get('sms_code')

        if not all([username, password, password2, mobile, allow]):
            return JsonResponse({'code': 400, 'errmsg': '用户信息不全'})

        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': 'password格式有误!'})
        # 判断两次密码是否一致
        if password != password2:
            return JsonResponse({'code': 400, 'errmsg': '两次输入密码不一致!'})
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': 'mobile格式有误!'})
        # 判断是否勾选用户协议
        if allow != True:
            return JsonResponse({'code': 400, 'errmsg': 'allow格式有误!'})

        # 保存注册数据
        user = User.objects.create_user(username=username, password=password, mobile=mobile)


        # 实现状态保持
        login(request, user)

        # 响应注册结果
        return JsonResponse({'code': 0, 'errmsg': '注册成功!'})

class LoginView(View):

    def post(self,request):
        """
        前端：POST请求 前端发送axios请求
        后端：
        1.接受数据
            json数据的接受 body
        2.业务逻辑
            2.1 数据是否存在 以及 数据类型的判断
            2.2 使用Django内的authenticate类判断数据是否在数据库中存在
            2.3 状态保持的判定
        3.返回数据
        """
        # 1. 从前端获取axios得到所需要的信息
        dict = json.loads(request.body.decode())
        username = dict.get('username')
        password = dict.get('password')
        remembered = dict.get('remembered')
        # 2. 判断用户名密码是否完整且正确 使用django内置的authenticate
        if not all([username,password]):
            return JsonResponse({'code':400,'errmsg':'缺少必需参数'})

        # 确定使用用户名还是密码登陆 修改User底层的判断对象
        if re.match('1[3-9]\d{9}',username):
            User.USERNAME_FIELD='mobile'
        else:
            User.USERNAME_FIELD='username'
        user = authenticate(username=username,password=password)

        if user is None:
            return JsonResponse({'code':400,'errmsg':'用户名或密码错误'})

        login(request,user)

        if remembered is not None:
            # 记住登陆用户两周
            request.session.set_expiry(None)
        else:
            # 浏览器关闭session过期
            request.session.set_expiry(0)

        response = JsonResponse({'code':0,'errmsg':'ok'})

        # 注册时用户名写入到cookie，有效期15天 用来展示用户名
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        return response

class LogoutView(View):

    def delete(self,request):
        """
            前端：类型：delete
            后端：与登陆的思路相反，登陆是保持一个session，推出登陆是删除在服务器中保持的session
                 可以直接使用django提供的logout方法
        """
        # 清理session
        logout(request)
        # 重定向到登陆界面
        response = JsonResponse({'code':0,'errmsg':'ok'})
        # 退出登录时清除cookie中的username
        response.delete_cookie('username')

        return response

class CenterView(LoginRequiredJSONMixin,View):
    # 注意在前后端分离的框架中未登录的用户会返回 重定向，重定向并不是Json数据，要重写方法
    # request.user就是已经登陆的用户的信息
    def get(self,request):

        info_data = {
            'username':request.user.username,
            'email':request.user.email,
            'mobile':request.user.mobile,
            'email_active':request.user.email_active
        }

        return JsonResponse({'code':0,'errmsg':'ok','info_data':info_data})


